home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / xlib05.zip / XMAIN.ASM < prev    next >
Assembly Source File  |  1993-08-25  |  44KB  |  1,407 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XMAIN
  3. ;
  4. ; Initialization, panning and split screen functions for all MODE X 256
  5. ; Color resolutions
  6. ;
  7. ; Compile with Tasm.
  8. ; C callable.
  9. ;
  10. ;
  11. ; ****** XLIB - Mode X graphics library                ****************
  12. ; ******                                               ****************
  13. ; ****** Written By Themie Gouthas                     ****************
  14. ;
  15. ; egg@dstos3.dsto.gov.au
  16. ; teg@bart.dsto.gov.au
  17. ;
  18. ; MODIFICATIONS:
  19. ;  26-9-92:          Pel panning code added
  20. ;  Dates forgotten:  Numerous ;^)
  21. ;-----------------------------------------------------------------------
  22.  
  23.  
  24. include xlib.inc
  25. include xmain.inc
  26.  
  27.  
  28.     .data
  29.  
  30.  
  31. ; Mode X CRTC register tweaks for various resolutions
  32.  
  33.  
  34. LABEL X256Y200 word
  35.         db      0e3h    ; dot clock
  36.         db      8       ; Number of CRTC Registers to update
  37.         dw      05f00h  ; horz total
  38.         dw      03f01h  ; horz displayed
  39.         dw      04202h  ; start horz blanking
  40.         dw      09f03h  ; end horz blanking
  41.         dw      04c04h  ; start h sync
  42.         dw      00005h  ; end h sync
  43.         dw      00014h  ; turn off dword mode
  44.         dw      0e317h  ; turn on byte mode
  45.         dw      256
  46.         dw      200
  47.  
  48.  
  49. LABEL X256Y240 word
  50.         db      0e3h    ; dot clock
  51.         db      16      ; Number of CRTC Registers to update
  52.         dw      05f00h  ; horz total
  53.         dw      03f01h  ; horz displayed
  54.         dw      04202h  ; start horz blanking
  55.         dw      09f03h  ; end horz blanking
  56.         dw      04c04h  ; start h sync
  57.         dw      00005h  ; end h sync
  58.         dw      00d06h  ; vertical total
  59.         dw      03e07h  ; overflow (bit 8 of vertical counts)
  60.         dw      04109h  ; cell height (2 to double-scan)
  61.         dw      0ea10h  ; v sync start
  62.         dw      0ac11h  ; v sync end and protect cr0-cr7
  63.         dw      0df12h  ; vertical displayed
  64.         dw      00014h  ; turn off dword mode
  65.         dw      0e715h  ; v blank start
  66.         dw      00616h  ; v blank end
  67.         dw      0e317h  ; turn on byte mode
  68.         dw      256
  69.         dw      240
  70.  
  71.  
  72. X320Y200 label  word
  73.     db      00      ; 0e3h    ; dot clock
  74.     db      02      ; Number of CRTC Registers to update
  75.     dw      00014h  ; turn off dword mode
  76.     dw      0e317h  ; turn on byte mode
  77.     dw      320     ; width
  78.     dw      200     ; height
  79.  
  80. X320Y240 label  word
  81.     db      0e3h    ; dot clock
  82.     db      10      ; Number of CRTC Registers to update
  83.     dw      00d06h  ; vertical total
  84.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  85.     dw      04109h  ; cell height (2 to double-scan)
  86.     dw      0ea10h  ; v sync start
  87.     dw      0ac11h  ; v sync end and protect cr0-cr7
  88.     dw      0df12h  ; vertical displayed
  89.     dw      00014h  ; turn off dword mode
  90.     dw      0e715h  ; v blank start
  91.     dw      00616h  ; v blank end
  92.     dw      0e317h  ; turn on byte mode
  93.     dw      320     ; width
  94.     dw      240     ; height
  95.  
  96. X360Y200 label  word
  97.     db      0e7h    ; dot clock
  98.     db      08      ; Number of CRTC Registers to update
  99.     dw      06b00h  ; horz total
  100.     dw      05901h  ; horz displayed
  101.     dw      05a02h  ; start horz blanking
  102.     dw      08e03h  ; end horz blanking
  103.     dw      05e04h  ; start h sync
  104.     dw      08a05h  ; end h sync
  105.     dw      00014h  ; turn off dword mode
  106.     dw      0e317h  ; turn on byte mode
  107.     dw      360     ; width
  108.     dw      200     ; height
  109.  
  110. X360Y240  label word
  111.     db      0e7h    ; dot clock
  112.     db      17      ; Number of CRTC Registers to update
  113.     dw      06b00h  ; horz total
  114.     dw      05901h  ; horz displayed
  115.     dw      05a02h  ; start horz blanking
  116.     dw      08e03h  ; end horz blanking
  117.     dw      05e04h  ; start h sync
  118.     dw      08a05h  ; end h sync
  119.     dw      00d06h  ; vertical total
  120.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  121.     dw      04109h  ; cell height (2 to double-scan)
  122.     dw      0ea10h  ; v sync start
  123.     dw      0ac11h  ; v sync end and protect cr0-cr7
  124.     dw      0df12h  ; vertical displayed
  125.     dw      02d13h  ; offset;
  126.     dw      00014h  ; turn off dword mode
  127.     dw      0e715h  ; v blank start
  128.     dw      00616h  ; v blank end
  129.     dw      0e317h  ; turn on byte mode
  130.     dw      360
  131.     dw      240
  132.  
  133. X376Y282 label word
  134.     db      0e7h
  135.     db      18
  136.     dw      06e00h  ; horz total
  137.     dw      05d01h  ; horz displayed
  138.     dw      05e02h  ; start horz blanking
  139.     dw      09103h  ; end horz blanking
  140.     dw      06204h  ; start h sync
  141.     dw      08f05h  ; end h sync
  142.     dw      06206h  ; vertical total
  143.     dw      0f007h  ; overflow
  144.     dw      06109h  ; cell height
  145.     dw      0310fh  ;
  146.     dw      03710h  ; v sync start
  147.     dw      08911h  ; v sync end and protect cr0-cr7
  148.     dw      03312h  ; vertical displayed
  149.     dw      02f13h  ; offset
  150.     dw      00014h  ; turn off dword mode
  151.     dw      03c15h  ; v blank start
  152.     dw      05c16h  ; v blank end
  153.     dw      0e317h  ; turn on byte mode
  154.     dw      376
  155.     dw      282
  156.  
  157. LABEL X256Y400 word
  158.         db      0e3h    ; dot clock
  159.         db      8       ; Number of CRTC Registers to update
  160.         dw      05f00h  ; horz total
  161.         dw      03f01h  ; horz displayed
  162.         dw      04202h  ; start horz blanking
  163.         dw      09f03h  ; end horz blanking
  164.         dw      04c04h  ; start h sync
  165.         dw      00005h  ; end h sync
  166.         dw      04009h  ; cell height
  167.         dw      00014h  ; turn off dword mode
  168.         dw      0e317h  ; turn on byte mode
  169.         dw      256
  170.         dw      400
  171.  
  172.  
  173. LABEL X256Y480 word
  174.         db      0e3h    ; dot clock
  175.         db      16      ; Number of CRTC Registers to update
  176.         dw      05f00h  ; horz total
  177.         dw      03f01h  ; horz displayed
  178.         dw      04202h  ; start horz blanking
  179.         dw      09f03h  ; end horz blanking
  180.         dw      04c04h  ; start h sync
  181.         dw      00005h  ; end h sync
  182.         dw      00d06h  ; vertical total
  183.         dw      03e07h  ; overflow (bit 8 of vertical counts)
  184.         dw      04009h  ; cell height (2 to double-scan)
  185.         dw      0ea10h  ; v sync start
  186.         dw      0ac11h  ; v sync end and protect cr0-cr7
  187.         dw      0df12h  ; vertical displayed
  188.         dw      00014h  ; turn off dword mode
  189.         dw      0e715h  ; v blank start
  190.         dw      00616h  ; v blank end
  191.         dw      0e317h  ; turn on byte mode
  192.         dw      256
  193.         dw      480
  194.  
  195.  
  196.  
  197. X320Y400 label  word
  198.     db      0e3h    ; dot clock
  199.     db      03      ; Number of CRTC Registers to update
  200.     dw      04009h  ; cell height
  201.     dw      00014h  ; turn off dword mode
  202.     dw      0e317h  ; turn on byte mode
  203.     dw      320     ; width
  204.     dw      400     ; height
  205.  
  206. X320Y480 label  word
  207.     db      0e3h    ; dotclock
  208.     db      10      ; Number of CRTC Registers to update
  209.     dw      00d06h  ; vertical total
  210.     dw      03e07h  ; overflow (bit 8 of vertical counts)
  211.     dw      04009h  ; cell height (2 to double-scan)
  212.     dw      0ea10h  ; v sync start
  213.     dw      0ac11h  ; v sync end and protect cr0-cr7
  214.     dw      0df12h  ; vertical displayed
  215.     dw      00014h  ; turn off dword mode
  216.     dw      0e715h  ; v blank start
  217.     dw      00616h  ; v blank end
  218.     dw      0e317h  ; turn on byte mode
  219.     dw      320     ; width
  220.     dw      480     ; height
  221.  
  222. X360Y400 label  word
  223.     db      0e7h    ; dot clock
  224.     db      09      ; Number of CRTC Registers to update
  225.     dw      06b00h  ; horz total
  226.     dw      05901h  ; horz displayed
  227.     dw      05a02h  ; start horz blanking
  228.     dw      08e03h  ; end horz blanking
  229.     dw      05e04h  ; start h sync
  230.     dw      08a05h  ; end h sync
  231.     dw      04009h  ; cell height
  232.     dw      00014h  ; turn off dword mode
  233.     dw      0e317h  ; turn on byte mode
  234.     dw      360     ; width
  235.     dw      400     ; height
  236.  
  237.  
  238.  
  239. X360Y480  label word
  240.     db      0e7h
  241.     db      17
  242.     dw      06b00h  ; horz total
  243.     dw      05901h  ; horz displayed
  244.     dw      05a02h  ; start horz blanking
  245.     dw      08e03h  ; end horz blanking
  246.     dw      05e04h  ; start h sync
  247.     dw      08a05h  ; end h sync
  248.     dw      00d06h  ; vertical total
  249.     dw      03e07h  ; overflow
  250.     dw      04009h  ; cell height
  251.     dw      0ea10h  ; v sync start
  252.     dw      0ac11h  ; v sync end and protect cr0-cr7
  253.     dw      0df12h  ; vertical displayed
  254.     dw      02d13h  ; offset
  255.     dw      00014h  ; turn off dword mode
  256.     dw      0e715h  ; v blank start
  257.     dw      00616h  ; v blank end
  258.     dw      0e317h  ; turn on byte mode
  259.     dw      360
  260.     dw      480
  261.  
  262. X360Y360  label word
  263.     db      0e7h
  264.     db      15
  265.     dw      06b00h  ; horz total
  266.     dw      05901h  ; horz displayed
  267.     dw      05a02h  ; start horz blanking
  268.     dw      08e03h  ; end horz blanking
  269.     dw      05e04h  ; start h sync
  270.     dw      08a05h  ; end h sync
  271.     dw      04009h  ; cell height
  272.     dw      08810h  ; v sync start
  273.     dw      08511h  ; v sync end and protect cr0-cr7
  274.     dw      06712h  ; vertical displayed
  275.     dw      02d13h  ; offset
  276.     dw      00014h  ; turn off dword mode
  277.     dw      06d15h  ; v blank start
  278.     dw      0ba16h  ; v blank end
  279.     dw      0e317h  ; turn on byte mode
  280.     dw      360
  281.     dw      360
  282.  
  283.  
  284. X376Y308 label word
  285.     db      0e7h
  286.     db      18
  287.     dw      06e00h  ; horz total
  288.     dw      05d01h  ; horz displayed
  289.     dw      05e02h  ; start horz blanking
  290.     dw      09103h  ; end horz blanking
  291.     dw      06204h  ; start h sync
  292.     dw      08f05h  ; end h sync
  293.     dw      06206h  ; vertical total
  294.     dw      00f07h  ; overflow
  295.     dw      04009h  ;
  296.     dw      0310fh  ;
  297.     dw      03710h  ; v sync start
  298.     dw      08911h  ; v sync end and protect cr0-cr7
  299.     dw      03312h  ; vertical displayed
  300.     dw      02f13h  ; offset
  301.     dw      00014h  ; turn off dword mode
  302.     dw      03c15h  ; v blank start
  303.     dw      05c16h  ; v blank end
  304.     dw      0e317h  ; turn on byte mode
  305.     dw      376
  306.     dw      308
  307.  
  308. X376Y564 label word
  309.     db      0e7h
  310.     db      18
  311.     dw      06e00h  ; horz total
  312.     dw      05d01h  ; horz displayed
  313.     dw      05e02h  ; start horz blanking
  314.     dw      09103h  ; end horz blanking
  315.     dw      06204h  ; start h sync
  316.     dw      08f05h  ; end h sync
  317.     dw      06206h  ; vertical total
  318.     dw      0f007h  ; overflow
  319.     dw      06009h  ;
  320.     dw      0310fh  ;
  321.     dw      03710h  ; v sync start
  322.     dw      08911h  ; v sync end and protect cr0-cr7
  323.     dw      03312h  ; vertical displayed
  324.     dw      02f13h  ; offset
  325.     dw      00014h  ; turn off dword mode
  326.     dw      03c15h  ; v blank start
  327.     dw      05c16h  ; v blank end
  328.     dw      0e317h  ; turn on byte mode
  329.     dw      376
  330.     dw      564
  331.  
  332. LAST_X_MODE         equ    13
  333. ModeTable label word    ; Mode X tweak table
  334.     dw      offset X320Y200
  335.     dw      offset X320Y240
  336.     dw      offset X360Y200
  337.     dw      offset X360Y240
  338.     dw      offset X376Y282
  339.     dw      offset X320Y400
  340.     dw      offset X320Y480
  341.     dw      offset X360Y400
  342.     dw      offset X360Y480
  343.     dw      offset X360Y360
  344.     dw      offset X376Y308
  345.     dw      offset X376Y564
  346.         dw      offset X256Y200
  347.     dw      offset X256Y240
  348.  
  349.  
  350. PARAMS label byte
  351.  
  352.     _CurrXMode               dw 0   ; Current graphics mode index
  353.     _InGraphics              db 0   ; Flag indicating graphics activity
  354.     _ScrnPhysicalByteWidth   dw 0   ; Physical width in bytes of screen
  355.     _ScrnPhysicalPixelWidth  dw 0   ; Physical width in pixels of screen
  356.     _ScrnPhysicalHeight      dw 0   ; Physical Height of screen
  357.     _ErrorValue              db 0   ; Set after function calls
  358.  
  359.  
  360.     _SplitScrnActive         db 0   ; Flag indicating Split scrn activity
  361.     _DoubleBufferActive      dw 0   ; Flag indicating double buffering
  362.  
  363.     _SplitScrnScanLine       dw 0   ; Split Screen's starting scan line
  364.     _SplitScrnVisibleHeight  dw 0   ; Split Screen's height on screen
  365.  
  366.     _SplitScrnOffs           dw 0   ; Offset in video ram of Split Screen
  367.                     ; always = 0
  368.     _Page0_Offs              dw 0   ; Ofset in video ram of Main virtual
  369.                     ; screen ( = 0 if no split screen
  370.                     ; otherwise = offset of first byte
  371.                     ; after split screen
  372.     _Page1_Offs              dw 0   ; Ofset in video ram of Second virtual
  373.                     ; screen ( = 0 if no split screen
  374.                     ; otherwise = offset of first byte
  375.                     ; after split screen
  376.                     ; = Page0_Offs if Doubble buffering
  377.                     ; not enabled
  378.     _NonVisual_Offs          dw 0   ; Ofset in video ram of first byte
  379.                     ; of non visible ram
  380.     _ScrnLogicalByteWidth    dw 0   ; Logical width in bytes of screen
  381.     _ScrnLogicalPixelWidth   dw 0   ; Logical width in pixels of screen
  382.     _ScrnLogicalHeight       dw 0   ; Logical Height of screen
  383.  
  384.     _MaxScrollX              dw 0   ; Max X start position of Physical
  385.                     ; screen within virtual screen (in
  386.                     ; bytes)
  387.     _MaxScrollY              dw 0   ; Max Y start position of Physical
  388.                     ; screen within virtual screen
  389.  
  390.     _VisiblePageIdx          dw 0   ; Index of currently visible D.B.
  391.                     ; page
  392.  
  393.     PageAddrTable label word
  394.     _VisiblePageOffs         dw 0   ; Table containing starting offsets
  395.     _HiddenPageOffs          dw 0   ; of the double buffer pages
  396.  
  397.     _TopClip                 dw 0   ; Clipping Rectangle
  398.     _BottomClip              dw 0   ;
  399.     _LeftClip                dw 0   ; Left/Right coordinates in bytes
  400.     _RightClip               dw 0   ;
  401.     _PhysicalStartByteX      dw 0   ; X byte coord of physical screen
  402.                     ; relative to virtual virtual screen
  403.     _PhysicalStartPixelX     dw 0   ; X pixel coord of physical screen
  404.                     ; relative to virtual screen
  405.     _PhysicalStartY          dw 0   ; Y pixel coord of physical screen
  406.                     ; relative to virtual screen
  407.  
  408. PARAMS_END label byte
  409.  
  410. PARAM_COUNT equ ($-PARAMS)
  411.  
  412.  
  413. ; Index/data pairs for CRT Controller registers that differ between
  414. ; mode 13h and mode X.
  415.  
  416.     ;Pelpan values for 0,1,2,3 pixel panning to the left, respectively
  417.     PelPanMask              db      000h,002h,004h,006h
  418.  
  419. DoubleScanFlag db ?     ; Flag to indicate double scanned mode
  420.  
  421.     .code
  422.  
  423. ;-------------------------------------------------------------------------
  424. ; Local Logical Screen Width setting function
  425. ; cx = Requitrd Logical Width
  426. ;
  427. ; WARNING: no registers are preserved
  428.  
  429. SetLogicalScrWidth proc
  430.     mov   dx,CRTC_INDEX
  431.     mov   al,CRTC_OFFSET
  432.     out   dx,al
  433.     inc   dx
  434.  
  435.     mov   ax,cx
  436.     cmp   ax,[_ScrnPhysicalPixelWidth]; Is logical width >= physical width
  437.     jge   @@ValidLogicalWidth          ; yes - continue
  438.     mov   ax,bx                        ; no - set logical width = physical
  439.  
  440. @@ValidLogicalWidth:
  441.     shr   ax,3
  442.     out   dx,al
  443.  
  444.     ; The EXACT logical pixel width may not have been possible since
  445.     ; it should be divisible by 8. Round down to the closest possible
  446.     ; width and update the status variables
  447.  
  448.     shl   ax,1
  449.     mov   bx,ax
  450.     mov   [_ScrnLogicalByteWidth],ax  ; Store the byte width of virtual
  451.     mov   [_RightClip],ax             ; Set default Right clip column
  452.                       ; screen
  453.     sub   ax,[_ScrnPhysicalByteWidth] ; Calculate and store Max X position
  454.     shl   ax,2                        ; of physical screen in virtual
  455.     mov   [_MaxScrollX],ax            ; screen in pixels
  456.     mov   ax,bx                       ; set ax to byte width of virt scrn
  457.     shl   ax,2                        ; convert to pixels
  458.     mov   [_ScrnLogicalPixelWidth],ax ; store virt scrn pixel width
  459.     mov   cx,ax                       ; save ax (return value)
  460.  
  461.     ; calculate no. non split screen rows in video ram
  462.  
  463.     mov   ax,0ffffh                ; cx = Maximum video ram offset
  464.     sub   dx,dx                    ; DX:AX is divide operand,  set DX = 0
  465.     div   bx                       ; divide ax by ScrnLogicalByteWidth
  466.     mov   [_ScrnLogicalHeight],ax  ; Save Screen Logical Height
  467.     mov   [_BottomClip],ax         ; Set default bottom clip row
  468.     sub   ax,[_ScrnPhysicalHeight] ; Update the maximum Y position of
  469.     mov   [_MaxScrollY],ax         ; Physical screen in logical screen
  470.     mov   ax,cx                    ; restore ax (return value)
  471.  
  472.     ; calculate initial NonVisual
  473.     mov  ax,[_ScrnLogicalByteWidth]
  474.     mul  [_ScrnPhysicalHeight]
  475.     mov  [_NonVisual_Offs],ax
  476.  
  477. @@Done: ret
  478. SetLogicalScrWidth endp
  479.  
  480. clear_vram proc
  481.         push  di
  482.     mov   dx,SC_INDEX
  483.     mov   ax,0f02h
  484.     out   dx,ax               ; enable writes to all four planes
  485.     mov   ax,SCREEN_SEG       ; now clear all display memory, 8 pixels
  486.     mov   es,ax               ; at a time
  487.     sub   di,di               ; point ES:DI to display memory
  488.  
  489.     WaitVsyncEnd
  490.  
  491.     sub   ax,ax               ; clear to zero-value pixels
  492.     mov   cx,0FFFFh           ; # of words in display memory
  493.     rep   stosw               ; clear all of display memory
  494.         pop   di
  495.     ret
  496. clear_vram endp
  497.  
  498.  
  499.  
  500. ;-----------------------------------------------------------------------
  501. ; Mode X graphics mode set with a virtual screen
  502. ;   logical screen width.
  503. ; C near-callable as:
  504. ;
  505. ;    int x_set_mode(unsigned int mode,unsigned int WidthInPixels);
  506. ;
  507. ; returns the actual width of the allocated virtual screen in pixels
  508. ; if a valid mode was selected otherwise returns -1
  509. ;
  510. ; Saves virtual screen pixel width in _ScrnLogicalPixelWidth.
  511. ; Saves virtual screen byte  width in _ScrnLogicalByteWidth.
  512. ; Physical screen dimensions are set in _ScrnPhysicalPixelWidth,
  513. ; _ScrnPhysicalByteWidth and _ScrnPhysicalHeight
  514. ;
  515. ;
  516. ; Modes:  0  = 320 x 200  (256 color)  NOTE: Some of these modes require
  517. ;         1  = 320 x 240  (256 color)     vertical size adjustment.
  518. ;         2  = 360 x 200  (256 color)
  519. ;         3  = 360 x 240  (256 color)
  520. ;         4  = 320 x 400  (256 color)
  521. ;         5  = 320 x 480  (256 color)
  522. ;         6  = 360 x 200  (256 color)
  523. ;         7  = 360 x 480  (256 color)
  524. ;         8  = 360 x 360  (256 color)
  525. ;         9  = 376 x 308  (256 color)
  526. ;         10 = 376 x 564  (256 color)
  527. ;
  528. ; Written by Themie Gouthas,
  529. ; parts adapted from M. Abrash code.
  530. ;------------------------------------------------------------------------
  531. _x_set_mode proc
  532.     ARG   mode:word,logicalscrwidth:word
  533.     push  bp      ;preserve caller's stack frame
  534.     mov   bp,sp
  535.  
  536.     push  si      ;preserve C register vars
  537.     push  di      ; (don't count on BIOS preserving anything)
  538.  
  539.     cld
  540.     mov   ax,ds
  541.     mov   es,ax
  542.     mov   di,offset PARAMS
  543.     xor   ax,ax
  544.     mov   cx,PARAM_COUNT
  545.     rep   stosb
  546.  
  547.     mov   cx,[mode]
  548.     cmp   cx,LAST_X_MODE        ; have we selected a valid mode
  549.     jle   @@ValidMode           ; Yes !
  550.  
  551.     mov   [_InGraphics],FALSE   ; No return -1
  552.     mov   ax,-1
  553.     pop   di
  554.     pop   si
  555.     pop   bp
  556.     ret
  557.  
  558. @@ValidMode:
  559.  
  560.     mov   [_CurrXMode],cx
  561.     mov   [_InGraphics],TRUE
  562.  
  563.     xor   al,al
  564.     cmp   cx,3
  565.     jg    @@SetDoubleScanFlag
  566.     mov   al,TRUE
  567. @@SetDoubleScanFlag:
  568.     mov   [DoubleScanFlag],al
  569.     push  cx                    ; some bios's dont preserve cx
  570.  
  571.     call  clear_vram
  572.  
  573.     mov   ax,13h                ; let the BIOS set standard 256-color
  574.     int   10h                   ;  mode (320x200 linear)
  575.  
  576.  
  577.     pop   cx
  578.  
  579.     mov   dx,SC_INDEX
  580.     mov   ax,0604h
  581.     out   dx,ax                 ; disable chain4 mode
  582.     mov   ax,0100h
  583.     out   dx,ax                 ; synchronous reset while setting Misc
  584.                     ;  Output for safety, even though clock
  585.                     ;  unchanged
  586.  
  587.     mov   bx,offset ModeTable
  588.     shl   cx,1
  589.     add   bx,cx
  590.     mov   si, word ptr [bx]
  591.     lodsb
  592.  
  593.     or    al,al
  594.     jz    @@DontSetDot
  595.     mov   dx,MISC_OUTPUT
  596.     out   dx,al               ; select the dot clock and Horiz
  597.                   ;  scanning rate
  598. @@DontSetDot:
  599.     mov   dx,SC_INDEX
  600.     mov   ax,0300h
  601.     out   dx,ax                ; undo reset (restart sequencer)
  602.  
  603.  
  604.     mov   dx,CRTC_INDEX       ; reprogram the CRT Controller
  605.     mov   al,11h              ; VSync End reg contains register write
  606.     out   dx,al               ; protect bit
  607.     inc   dx                  ; CRT Controller Data register
  608.     in    al,dx               ; get current VSync End register setting
  609.     and   al,07fh             ; remove write protect on various
  610.     out   dx,al               ; CRTC registers
  611.     dec   dx                  ; CRT Controller Index
  612.     cld
  613.     xor   cx,cx
  614.     lodsb
  615.     mov   cl,al
  616.  
  617. @@SetCRTParmsLoop:
  618.     lodsw                     ; get the next CRT Index/Data pair
  619.     out   dx,ax               ; set the next CRT Index/Data pair
  620.     loop  @@SetCRTParmsLoop
  621.  
  622.     mov   dx,SC_INDEX
  623.     mov   ax,0f02h
  624.     out   dx,ax               ; enable writes to all four planes
  625.     mov   ax,SCREEN_SEG       ; now clear all display memory, 8 pixels
  626.     mov   es,ax               ; at a time
  627.     sub   di,di               ; point ES:DI to display memory
  628.     sub   ax,ax               ; clear to zero-value pixels
  629.     mov   cx,8000h            ; # of words in display memory
  630.     rep   stosw               ; clear all of display memory
  631.  
  632.  
  633.     ;Fix for single line
  634.  
  635.     ;mov   dx,CRTC_INDEX
  636.     ;mov   al,MAX_SCAN_LINE
  637.     ;out   dx,al
  638.     ;inc   dx
  639.     ;mov   al,0C0h
  640.     ;out   dx,al
  641.  
  642.     ;  Set pysical screen dimensions
  643.  
  644.     lodsw                               ; Load scrn pixel width
  645.     mov   [_ScrnPhysicalPixelWidth],ax  ;  from tweak table and store
  646.     mov   [_SplitScrnScanLine],ax       ; No splitscrn ==
  647.                         ; splitscrn=PhysicalscrnHeight
  648.     mov   bx,ax                         ; Copy width for later use
  649.     shr   ax,2                          ; Convert to byte width
  650.     mov   [_ScrnPhysicalByteWidth],ax   ; Store for later use
  651.     lodsw                               ; Load Screen Phys. Height
  652.     mov   [_ScrnPhysicalHeight],ax      ; Store for later use
  653.  
  654.  
  655.     ;  Mode X is set, now set the required logical page width.
  656.  
  657.     mov     cx,[logicalscrwidth]
  658.  
  659.     call    SetLogicalScrWidth
  660.  
  661.     pop     di      ;restore C register vars
  662.     pop     si
  663.     pop     bp      ;restore caller's stack frame
  664.     ret
  665. _x_set_mode endp
  666.  
  667. ;----------------------------------------------------------------------
  668. ; Mode X (256 color mode) set default access video plane
  669. ;
  670. ; C near-callable as:
  671. ;    void x_select_default_plane(unsigned char plane);
  672. ;
  673. ; Enables Read/Write access to a plane using general memory access
  674. ; methods
  675. ;
  676. ; Written by Themie Gouthas
  677. ;----------------------------------------------------------------------
  678. _x_select_default_plane proc
  679. ARG Plane:byte
  680.     push bp
  681.     mov  bp,sp       ; set up stack frame
  682.     mov  cl,byte ptr [Plane]
  683.  
  684.     ; SELECT WRITE PLANE
  685.     and  cl,011b              ;CL = plane
  686.     mov  ax,0100h + MAP_MASK  ;AL = index in SC of Map Mask reg
  687.     shl  ah,cl                ;set only the bit for the required
  688.                   ; plane to 1
  689.     mov  dx,SC_INDEX          ;set the Map Mask to enable only the
  690.     out  dx,ax                ; pixel's plane
  691.  
  692.     ; SELECT READ PLANE
  693.     mov  ah,cl                ;AH = plane
  694.     mov  al,READ_MAP          ;AL = index in GC of the Read Map reg
  695.     mov  dx,GC_INDEX          ;set the Read Map to read the pixel's
  696.     out  dx,ax                ; plane
  697.  
  698.     pop  bp
  699.     ret
  700. _x_select_default_plane endp
  701.  
  702.  
  703. ;----------------------------------------------------------------------
  704. ; Mode X (256 color mode) Set Mode X split screen starting row
  705. ; The split screen resides on the bottom half of the screen and has a
  706. ; starting address of A000:0000
  707. ;
  708. ; C near-callable as:
  709. ;    void x_set_splitscreen(unsigned int line);
  710. ;
  711. ; Updates _Page0_Offs to reflect the existence of the split screen region
  712. ; ie _MainScrnOffset is set to the offset of the first pixel beyond the split
  713. ; screen region
  714. ;
  715. ; Written by Themie Gouthas
  716. ;----------------------------------------------------------------------
  717.  
  718. _x_set_splitscreen proc
  719.     ARG Line:word
  720.     push bp
  721.     mov  bp,sp       ; set up stack frame
  722.     push si
  723.  
  724.     xor  si,si       ; si=0 -> x virtual page start coord
  725.  
  726.     cmp  [_DoubleBufferActive],0
  727.     jne   @@error
  728.  
  729.     cmp  [_SplitScrnActive],0
  730.     je   @@NotPreviouslyCalled
  731.  
  732. @@error:
  733.     mov  [_ErrorValue],ERROR
  734.     pop  si
  735.     pop  bp          ; Return if previously called
  736.     ret
  737.  
  738. @@NotPreviouslyCalled:
  739.  
  740.     ; Turn on split screen pal pen suppression, so the split screen
  741.     ; wo'nt be subject to pel panning as is the non split screen portion.
  742.  
  743.     mov  dx,INPUT_STATUS_0
  744.     in   al,dx                  ; Reset the AC Index/Data toggle to
  745.                     ;  index state
  746.     mov  al,AC_MODE_CONTROL+20h ; Bit 5 set to prevent screen blanking
  747.     mov  dx,AC_INDEX            ; Point AC to Index/Data register
  748.     out  dx,al
  749.     inc  dx                     ; Point to AC Data reg (for reads only)
  750.     in   al,dx                  ; Get the current AC Mode Control reg
  751.     or   al,20h                 ; Enable split scrn Pel panning suppress.
  752.     dec  dx                     ; Point to AC Index/Data reg (for writes only)
  753.     out  dx,al                  ; Write the new AC Mode Control setting
  754.                     ;  with split screen pel panning
  755.                     ;  suppression turned on
  756.  
  757.     mov  [_PhysicalStartByteX],ax   ; Set the Phisical screen start
  758.     mov  [_PhysicalStartPixelX],ax  ; offset within virtual screen
  759.     mov  [_PhysicalStartY],ax
  760.     mov  [_SplitScrnActive],TRUE
  761.     mov  ax,[Line]
  762.     jns  @@NotNeg    ; Check that Split Scrn start scan line is +ve
  763.  
  764.     mov  ax,0        ; Since -ve set to 0
  765.  
  766. @@NotNeg:
  767.     mov  [_SplitScrnScanLine],ax   ; save the scanline
  768.  
  769.  
  770.  
  771.     or    [DoubleScanFlag],0
  772.     jz    @@NotDoubleScanned
  773.     shl   ax,1
  774.     dec   ax
  775. @@NotDoubleScanned:
  776.     ;mov  cl,[DoubleScanFlag]
  777.     ;shl  ax,cl            ; Mode X 200 and 240 line modes are actually
  778.                   ; 400 and 480 lines that are double scanned
  779.                   ; so for start scanline multiply required ModeX
  780.                   ; scan line by 2 if its a double scanned mode
  781.  
  782.  
  783.     mov  bx,ax            ; save the scanline
  784.  
  785.  
  786.     WaitVsyncStart        ; wait for vertical retrace
  787.  
  788.     cli                   ; Dont allow register setting to be interrupted
  789.     mov  dx,CRTC_INDEX
  790.     mov  ah,bl
  791.     mov  al,LINE_COMPARE
  792.     out  dx,ax            ; Bits 7-0 of the split screen scan line
  793.  
  794.     mov  ah,bh
  795.     and  ah,1
  796.     shl  ah,4
  797.     mov  al,OVERFLOW     ; Bit 4 of overflow register = Bit 8 of split
  798.     out  dx,al           ; screen scan line,
  799.     inc  dx              ; So using readability of VGA registers
  800.     in   al,dx           ; Read the OVERFLOW register, and set the
  801.     and  al, not 10h     ; bit corresponding to Bit 8 (above)
  802.     or   al,ah
  803.     out  dx,al
  804.  
  805.     dec  dx
  806.     mov  ah,bh
  807.     and  ah,2
  808.     ror  ah,3
  809.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  810.     out  dx,al             ; Bit 9 of split screen scan line
  811.     inc  dx                ; As we did before, update the apropriate
  812.     in   al,dx             ; bit without disturbing the rest
  813.     and  al, not 40h
  814.     or   al,ah
  815.     out  dx,al
  816.     sti                    ; Registers are set, so interrupts are safe
  817.  
  818.     mov  ax,[_ScrnPhysicalHeight]     ; Determine where the first byte
  819.     sub  ax,[_SplitScrnScanLine]      ; of the non split screen video ram
  820.     mov  [_SplitScrnVisibleHeight],bx ; starts and store it for reference
  821.  
  822.     mov  bx,[_ScrnLogicalByteWidth]
  823.     mul  bx
  824.     mov  [_Page0_Offs],ax
  825.     mov  [_Page1_Offs],ax
  826.  
  827.     ; calculate no. non split screen rows in video ram
  828.     mov  cx,0ffffh             ; cx = Maximum video ram offset
  829.     sub  cx,ax                 ; cx = cx - _Page0_Offs
  830.     xchg cx,ax                 ; swap cx and ax
  831.     sub  dx,dx                 ; DX:AX is divide operand,  set DX = 0
  832.     div  bx                    ; divide ax (prev cx) by
  833.                    ; ScrnLogicalByteWidth
  834.  
  835.     mov  [_ScrnLogicalHeight],ax     ; Save Screen Logical Height
  836.     cmp   ax,[_BottomClip]
  837.     jle   @@BottomClipOK             ; Adjust Clip Rectangle if necessary
  838.     mov   [_BottomClip],ax
  839. @@BottomClipOK:
  840.     sub  ax,[_SplitScrnScanLine]     ; Update the maximum Y position of
  841.     mov  [_MaxScrollY],ax            ; Physical screen in logical screen
  842.  
  843.     xchg cx,ax                    ; restore original ax (MainScrnOfs)
  844.     mov  bh,al                    ; Set the visible screen start address
  845.     mov  ch,ah                    ; to the top left corner of the virtual
  846.     jmp  short StartAddrEntry     ; screen
  847. _x_set_splitscreen      endp
  848.  
  849.  
  850. ;-----------------------------------------------------------------------
  851. ; Mode X (256 color mode) Page flip primer
  852. ; No clipping is performed.
  853. ; C near-callable as:
  854. ;
  855. ;    void x_page_flip(unsigned int x, unsigned int y);
  856. ;
  857. ; Swaps visible and hidden page offsets and then executes the SetStartAddr
  858. ; to achieve a page flip.
  859. ;
  860. ; SEE x_set_start_addr below
  861. ;
  862. ; Written by Themie Gouthas
  863. ;------------------------------------------------------------------------
  864.  
  865. _x_page_flip proc
  866.     ARG x:word,y:word
  867.     push  bp                  ;preserve caller's stack frame
  868.     mov   bp,sp               ;point to local stack frame
  869.     push  si
  870.  
  871.     mov  si,[x]
  872.     mov  ax,[_ScrnLogicalByteWidth]     ; Calculate Offset increment
  873.     mov  cx,[y]
  874.     mul  cx                             ; for Y
  875.     cmp  [_DoubleBufferActive],TRUE     ; Do we have double buffering ?
  876.     jne  PageFlipEntry1
  877.  
  878.     mov  bx,[_HiddenPageOffs]
  879.     xchg bx,[_VisiblePageOffs]          ; Swap the Page Offsete
  880.     xchg [_HiddenPageOffs],bx
  881.     xor  [_VisiblePageIdx],01h          ; Set the Visible page index
  882.     jmp  short PageFlipEntry2
  883. _x_page_flip endp
  884.  
  885.  
  886. ;-----------------------------------------------------------------------
  887. ; Mode X (256 color mode) Set Mode X non split screen start address
  888. ;   of logical screen.
  889. ; C near-callable as:
  890. ;
  891. ;    void x_set_start_addr(unsigned int x, unsigned int y);
  892. ;
  893. ; Params: StartOffset is offset of first byte of logical screen ram
  894. ;           (Useful if you want to double buffer by splitting your non
  895. ;            split screen video ram into 2 pages)
  896. ;        X,Y coordinates of the top left hand corner of the physical screen
  897. ;           within the logical screen
  898. ;           X must not exceed (Logical screen width - Physical screen width)
  899. ;           Y must not exceed (Logical screen height - Physical screen height)
  900. ;
  901. ;
  902. ; Written by Themie Gouthas,
  903. ; Parts addapted from M. Abrash code published in DDJ Mag.
  904. ;------------------------------------------------------------------------
  905. _x_set_start_addr proc
  906.     ARG x:word,y:word
  907.     push bp
  908.     mov  bp,sp
  909.     push si
  910.  
  911.     mov  si,[x]
  912.     mov  ax,[_ScrnLogicalByteWidth]     ; Calculate Offset increment
  913.     mov  cx,[y]                         ; for Y
  914.     mul  cx
  915.     cmp  [_DoubleBufferActive],TRUE     ; Do we have double buffering ?
  916.     je   @@PageResolution
  917. PageFlipEntry1:
  918.     add  ax,[_Page0_Offs]               ; no - add page 0 offset
  919.     jmp  short @@AddColumn
  920.  
  921. PageFlipEntry2:
  922.  
  923.     mov  [_PhysicalStartPixelX],si
  924.     mov  [_PhysicalStartY],cx
  925.  
  926. @@PageResolution:
  927.     add  ax,[_VisiblePageOffs]          ; Add visible page offset
  928.  
  929. @@AddColumn:
  930.     mov  cx,si
  931.     shr  cx,2
  932.     mov  [_PhysicalStartByteX],cx
  933.     add  ax,cx                          ; add the column offset for X
  934.     mov  bh,al                          ; setup CRTC start addr regs and
  935.                         ; values in word registers for
  936.     mov  ch,ah                          ; fast word outs
  937.  
  938. StartAddrEntry:
  939.     mov  bl,ADDR_LOW
  940.     mov  cl,ADDR_HIGH
  941.     and  si,0003h             ; select pel pan register value for the
  942.     mov  ah,PelPanMask[si]    ; required x coordinate
  943.     mov  al,PEL_PANNING+20h
  944.     mov  si,ax
  945.  
  946.     mov  dx,INPUT_STATUS_0    ;Wait for trailing edge of Vsync pulse
  947. @@WaitDE:
  948.     in   al,dx
  949.     test al,01h
  950.     jnz  @@WaitDE            ;display enable is active low (0 = active)
  951.  
  952.     mov  dx,CRTC_INDEX
  953.     mov  ax,bx
  954.     cli
  955.     out  dx,ax               ;start address low
  956.     mov  ax,cx
  957.     out  dx,ax               ;start address high
  958.     sti
  959.  
  960. ; Now wait for vertical sync, so the other page will be invisible when
  961. ; we start drawing to it.
  962.     mov  dx,INPUT_STATUS_0    ;Wait for trailing edge of Vsync pulse
  963. @@WaitVS:
  964.     in   al,dx
  965.     test al,08h
  966.     jz @@WaitVS           ;display enable is active low (0 = active)
  967.  
  968.  
  969.     mov  dx,AC_INDEX
  970.     mov  ax,si                ; Point the attribute controller to pel pan
  971.     cli
  972.     out  dx,al                ; reg. Bit 5 also set to prevent blanking
  973.     mov  al,ah
  974.     out  dx,al                ; load new Pel Pan setting.
  975.     sti
  976.  
  977.     mov  [_ErrorValue],OK
  978.     pop  si
  979.     pop  bp
  980.     ret
  981. _x_set_start_addr  endp
  982.  
  983.  
  984. ;-----------------------------------------------------------------------
  985. ; Mode X (256 color mode) Mode X split screen hide
  986. ; C near-callable as:
  987. ;
  988. ;    void x_hide_splitscreen()
  989. ;
  990. ; Hides an existing split screen by setting its starting scan line to
  991. ; the last physical screen scan line
  992. ;
  993. ; WARNING: Only to be used if SplitScrnLine has been previously called
  994. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  995. ;          the initial split screen is reserved and the size limitations
  996. ;          of these modes means any change in the split screen scan line
  997. ;          will encroach on the split screen ram
  998. ;
  999. ; Written by Themie Gouthas
  1000. ;------------------------------------------------------------------------
  1001.  
  1002. _x_hide_splitscreen proc
  1003.     push bp
  1004.     mov  bp,sp
  1005.  
  1006.     cmp  [_SplitScrnActive],TRUE
  1007.     je   @@SplitScreenEnabled
  1008.  
  1009. @@error:
  1010.     mov  [_ErrorValue],ERROR
  1011.     pop  bp
  1012.     ret
  1013.  
  1014. @@SplitScreenEnabled:
  1015.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  1016.     jg   @@error
  1017.     mov  bx,[_ScrnPhysicalHeight]
  1018.  
  1019.     mov  ax,[_ScrnLogicalHeight]
  1020.     sub  ax,bx
  1021.     mov  [_MaxScrollY],ax
  1022.     xor  ax,ax
  1023.     mov  [_SplitScrnVisibleHeight],ax
  1024.  
  1025.     or    [DoubleScanFlag],0
  1026.     jz    @@NotDoubleScanned
  1027.     shl   bx,1
  1028.     dec   bx
  1029. @@NotDoubleScanned:
  1030.     ;mov  cl,[DoubleScanFlag]  ; Compensate for double scanned modes
  1031.     ;shl  bx,cl
  1032.  
  1033.     WaitVsyncStart               ; wait for vertical retrace
  1034.  
  1035.     cli                 ; Dont allow register setting to be interrupted
  1036.     mov  dx,CRTC_INDEX
  1037.     mov  ah,bl
  1038.     mov  al,LINE_COMPARE
  1039.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  1040.  
  1041.     mov  ah,bh
  1042.     and  ah,1
  1043.     shl  ah,4
  1044.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  1045.     out  dx,al        ; screen scan line,
  1046.     inc  dx           ; So using readability of VGA registers
  1047.     in   al,dx        ; Read the OVERFLOW register, and set the
  1048.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1049.     or   al,ah
  1050.     out  dx,al
  1051.  
  1052.     dec  dx
  1053.     mov  ah,bh
  1054.     and  ah,2
  1055.     ror  ah,3
  1056.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1057.     out  dx,al             ; Bit 9 of split screen scan line
  1058.     inc  dx                ; As we did before, update the apropriate
  1059.     in   al,dx             ; bit without disturbing the rest
  1060.     and  al, not 40h
  1061.     or   al,ah
  1062.     out  dx,al
  1063.     sti                  ; Registers are set, so interrupts are safe
  1064.  
  1065. @@done:
  1066.  
  1067.     mov  [_ErrorValue],OK
  1068.     pop  bp
  1069.     ret
  1070. _x_hide_splitscreen endp
  1071.  
  1072. ;-----------------------------------------------------------------------
  1073. ; Mode X (256 color mode) Mode X split screen show
  1074. ; C near-callable as:
  1075. ;
  1076. ;    void x_show_splitscreen()
  1077. ;
  1078. ; Restores split screen start scan line to the initial split screen
  1079. ; starting scan line as set by SplitScrnLine.
  1080. ;
  1081. ; WARNING: Only to be used if SplitScrnLine has been previously called
  1082. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  1083. ;          the initial split screen is reserved and the size limitations
  1084. ;          of these modes means any change in the split screen scan line
  1085. ;          will encroach on the split screen ram
  1086. ;          Update: Now disabled for these modes
  1087. ;
  1088. ; Written by Themie Gouthas
  1089. ;------------------------------------------------------------------------
  1090.  
  1091.  
  1092. _x_show_splitscreen proc
  1093.     push bp
  1094.     mov  bp,sp
  1095.  
  1096.     cmp  [_SplitScrnActive],TRUE
  1097.     je   @@SplitScreenEnabled
  1098.  
  1099. @@error:
  1100.     mov  [_ErrorValue],ERROR
  1101.     pop  bp
  1102.     ret
  1103.  
  1104. @@SplitScreenEnabled:
  1105.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  1106.     jg   @@error
  1107.  
  1108.     mov  bx,[_SplitScrnScanLine]
  1109.     mov  ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
  1110.     sub  ax,bx
  1111.     mov  [_MaxScrollY],ax
  1112.  
  1113.     mov  ax,[_ScrnPhysicalHeight]
  1114.     sub  ax,bx
  1115.     mov  [_SplitScrnVisibleHeight],ax
  1116.  
  1117.     or    [DoubleScanFlag],0
  1118.     jz    @@NotDoubleScanned
  1119.     shl   bx,1
  1120.     dec   bx
  1121. @@NotDoubleScanned:
  1122.     ;mov  cl,[DoubleScanFlag]  ; Compensate for double scanned modes
  1123.     ;shl  bx,cl
  1124.     WaitVsyncStart               ; wait for vertical retrace
  1125.  
  1126.     cli                 ; Dont allow register setting to be interrupted
  1127.     mov  dx,CRTC_INDEX
  1128.     mov  ah,bl
  1129.     mov  al,LINE_COMPARE
  1130.     out  dx,ax                  ; Bits 7-0 of the split screen scan line
  1131.  
  1132.     mov  ah,bh
  1133.     and  ah,1
  1134.     shl  ah,4
  1135.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  1136.     out  dx,al        ; screen scan line,
  1137.     inc  dx           ; So using readability of VGA registers
  1138.     in   al,dx        ; Read the OVERFLOW register, and set the
  1139.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1140.     or   al,ah
  1141.     out  dx,al
  1142.  
  1143.     dec  dx
  1144.     mov  ah,bh
  1145.     and  ah,2
  1146.     ror  ah,3
  1147.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1148.     out  dx,al             ; Bit 9 of split screen scan line
  1149.     inc  dx                ; As we did before, update the apropriate
  1150.     in   al,dx             ; bit without disturbing the rest
  1151.     and  al, not 40h
  1152.     or   al,ah
  1153.     out  dx,al
  1154.     sti                  ; Registers are set, so interrupts are safe
  1155.  
  1156. @@Done:
  1157.     mov  [_ErrorValue],0
  1158.     pop  bp
  1159.     ret
  1160. _x_show_splitscreen endp
  1161.  
  1162.  
  1163. ;-----------------------------------------------------------------------
  1164. ; Mode X (256 color mode) Modify Mode X split screen starting scan line
  1165. ; C near-callable as:
  1166. ;
  1167. ;    void x_adjust_splitscreen(unsigned int ScanLine)
  1168. ;
  1169. ; Sets the split screen start scan line to a new scan line. Valid scan lines
  1170. ; are between the initial split screen starting scan line and the last
  1171. ; physical screen scan line.
  1172. ;
  1173. ; WARNING: Only to be used if SplitScrnLine has been previously called
  1174. ; WARNING: DO NOT USE with mode 5-11 (320x400-376x564). The memory for
  1175. ;          the initial split screen is reserved and the size limitations
  1176. ;          of these modes means any change in the split screen scan line
  1177. ;          will encroach on the split screen ram
  1178. ;          Update: Now disabled for these modes
  1179. ;
  1180. ;
  1181. ; Written by Themie Gouthas
  1182. ;------------------------------------------------------------------------
  1183.  
  1184.  
  1185. _x_adjust_splitscreen proc
  1186.     ARG   ScanLine
  1187.     push bp
  1188.     mov  bp,sp
  1189.  
  1190.     cmp  [_SplitScrnActive],TRUE
  1191.     je   @@SplitScreenEnabled
  1192.  
  1193. @@error:
  1194.     mov  [_ErrorValue],ERROR
  1195.     pop  bp
  1196.     ret
  1197.  
  1198. @@SplitScreenEnabled:
  1199.     cmp  [_CurrXMode],4          ; Do nothing for Modes > 2
  1200.     jg   @@error
  1201.     mov  bx,[ScanLine]            ; Is the required starting scan line
  1202.     cmp  bx,[_SplitScrnScanLine]  ; valid ?
  1203.     js   @@Done                   ; No - Then do nothing
  1204.  
  1205. @@ValidScanLine:
  1206.  
  1207.     mov  ax,[_ScrnLogicalHeight] ; Update Max Scroll Y
  1208.     sub  ax,bx
  1209.     mov  [_MaxScrollY],ax
  1210.  
  1211.     mov  ax,[_ScrnPhysicalHeight]
  1212.     sub  ax,bx
  1213.     mov  [_SplitScrnVisibleHeight],ax
  1214.  
  1215.     or    [DoubleScanFlag],0
  1216.     jz    @@NotDoubleScanned
  1217.     shl   bx,1
  1218.     dec   bx
  1219. @@NotDoubleScanned:
  1220.     ;mov  cl,[DoubleScanFlag]   ; Compensate for double scanned modes
  1221.     ;shl  bx,cl
  1222.  
  1223.     WaitVsyncStart      ; wait for vertical retrace
  1224.  
  1225.     cli                 ; Dont allow register setting to be interrupted
  1226.  
  1227.     mov  dx,CRTC_INDEX
  1228.     mov  ah,bl
  1229.     mov  al,LINE_COMPARE
  1230.     out  dx,ax          ; Bits 7-0 of the split screen scan line
  1231.  
  1232.     mov  ah,bh
  1233.     and  ah,1
  1234.     shl  ah,4
  1235.     mov  al,OVERFLOW  ; Bit 4 of overflow register = Bit 8 of split
  1236.     out  dx,al        ; screen scan line,
  1237.     inc  dx           ; So using readability of VGA registers
  1238.     in   al,dx        ; Read the OVERFLOW register, and set the
  1239.     and  al, not 10h  ; bit corresponding to Bit 8 (above)
  1240.     or   al,ah
  1241.     out  dx,al
  1242.  
  1243.     dec  dx
  1244.     mov  ah,bh
  1245.     and  ah,2
  1246.     ror  ah,3
  1247.     mov  al,MAX_SCAN_LINE  ; Bit 6 of max scan line register =
  1248.     out  dx,al             ; Bit 9 of split screen scan line
  1249.     inc  dx                ; As we did before, update the apropriate
  1250.     in   al,dx             ; bit without disturbing the rest
  1251.     and  al, not 40h
  1252.     or   al,ah
  1253.     out  dx,al
  1254.     sti                    ; Registers are set, so interrupts are safe
  1255. @@Done:
  1256.     mov  [_ErrorValue],OK
  1257.     pop   bp
  1258.     ret
  1259. _x_adjust_splitscreen endp
  1260.  
  1261.  
  1262.  
  1263. ;-----------------------------------------------------------------------
  1264. ; Mode X (256 color mode) Enable DoubleBuffering on non split screen area
  1265. ; C near-callable as:
  1266. ;
  1267. ;    int x_set_doublebuffer(unsigned int PageHeight);
  1268. ;
  1269. ; Params: PageHeight is the height of the virtual screen to double buffer
  1270. ;         Returns the closest possible height to the specified.
  1271. ;
  1272. ; Sets up two double buffering virtual pages
  1273. ; GLOBAL variables set:
  1274. ;
  1275. ;      _Page1_Offs              Offset of second virtual page
  1276. ;      _NonVisual_Offs          Offset of first non visible video ram byte
  1277. ;      _DoubleBufferActive      Flag
  1278. ;      _PageAddrTable           Table of Double buffering pages start offsets
  1279. ;      _ScrnLogicalHeight       Logical height of the double buffering pages
  1280. ;
  1281. ;
  1282. ; Written by Themie Gouthas
  1283. ;------------------------------------------------------------------------
  1284.  
  1285.  
  1286. _x_set_doublebuffer proc
  1287.        ARG PageHeight:word
  1288.        push  bp
  1289.        mov   bp,sp
  1290.  
  1291.        cmp   [_DoubleBufferActive],0
  1292.        je    @@OkToContinue
  1293. @error:
  1294.        mov   [_ErrorValue],ERROR
  1295.        pop   bp
  1296.        ret
  1297.  
  1298. @@OkToContinue:
  1299.        mov   [_VisiblePageIdx],0     ; Set visible Page to 0
  1300.        mov   ax,[_ScrnLogicalHeight] ; Set Maximum D.B. Page height to
  1301.        shr   ax,1                    ;   _ScrnLogicalHeight / 2
  1302.  
  1303.        mov   bx,[PageHeight]         ; Is the require D.B. Page Height
  1304.        cmp   ax,bx                   ;  > the Maximum  D.B. Page Height ?
  1305.  
  1306.        js    @@InvalidHeight         ; no  - jump
  1307.        mov   ax,bx                   ; yes - Set the D.B. Page height to
  1308.                      ;       to the maximum allowed.
  1309.  
  1310. @@InvalidHeight:
  1311.        mov   [_ScrnLogicalHeight],ax    ; Update logical screen height to
  1312.                     ;  reflect the height of a D.B. page
  1313.        cmp   ax,[_BottomClip]
  1314.        jle   @@BottomClipOK             ; Adjust Clip Rectangle if necessary
  1315.        mov   [_BottomClip],ax
  1316. @@BottomClipOK:
  1317.        mov   dx,ax
  1318.        mul   [_ScrnLogicalByteWidth]    ; Calculate the offset of the second
  1319.        mov   cx,ax                      ;  D.B. Page in video ram
  1320.        mov   bx,[_Page0_Offs]
  1321.        mov   [_VisiblePageOffs],bx
  1322.  
  1323.        add   ax,bx
  1324.        mov   [_Page1_Offs],ax           ; Save it
  1325.        mov   [_HiddenPageOffs],ax
  1326.  
  1327.        add   ax,cx                      ; Calculate the offset of first byte
  1328.        mov   [_NonVisual_Offs],ax       ;  beyond the D.B. pages and save it
  1329.        mov   [_DoubleBufferActive],TRUE ; Set flag indicating D.B'ing mode on
  1330.  
  1331.        mov   ax,dx
  1332.        sub   ax,[_ScrnPhysicalHeight]
  1333.        add   ax,[_SplitScrnVisibleHeight]
  1334.        mov   [_MaxScrollY],ax
  1335.  
  1336.        mov   ax,dx                      ; return the D.B. pages' height
  1337.        mov   [_ErrorValue],OK
  1338.        pop   bp
  1339.        ret
  1340. _x_set_doublebuffer endp
  1341.  
  1342.  
  1343. ;-----------------------------------------------------------------------
  1344. ; Set Clipping rectangle
  1345. ; C callable as:
  1346. ;
  1347. ;
  1348. ;    int x_set_cliprect(WORD left,WORD top, WORD right, WORD bottom);
  1349. ;
  1350. ;
  1351. ; NOTE clipping is byte oriented. "left" and "right" are in bytes not pixels.
  1352. ;    Only selected functions perform any clipping at all.
  1353. ;
  1354. ; Written by Themie Gouthas
  1355. ;------------------------------------------------------------------------
  1356.  
  1357. _x_set_cliprect proc
  1358. ARG left:word,top:word,right:word,bottom:word
  1359.        push  bp
  1360.        mov   bp,sp
  1361.        mov   ax,[left]
  1362.        mov   bx,[right]
  1363.        cmp   bx,ax
  1364.        jns   @@CorrectXOrder
  1365.        xchg  bx,ax
  1366. @@CorrectXOrder:
  1367.        mov   [_LeftClip],ax
  1368.        mov   [_RightClip],bx
  1369.        mov   ax,[top]
  1370.        mov   bx,[bottom]
  1371.        cmp   bx,ax
  1372.        jns   @@CorrectYOrder
  1373.        xchg  bx,ax
  1374. @@CorrectYOrder:
  1375.        mov   [_TopClip],ax
  1376.        mov   [_BottomClip],bx
  1377.        pop   bp
  1378.        ret
  1379. _x_set_cliprect endp
  1380.  
  1381.  
  1382. ;----------------------------------------------------------------------
  1383. ; Return to text mode
  1384. ;
  1385. _x_text_mode proc
  1386.        push  bp
  1387.        call  clear_vram
  1388.        mov   ax,03h        ; Restore Text Mode
  1389.        int   10h
  1390.  
  1391.        pop   bp
  1392.        ret
  1393. _x_text_mode endp
  1394.  
  1395. ;-----------------------------------------------------------------------
  1396. ; Wait for Vertical sync
  1397. _x_wait_vsync proc
  1398.     push  bp
  1399.     WaitVsyncStart
  1400.     pop   bp
  1401.     ret
  1402. _x_wait_vsync endp
  1403.  
  1404.  
  1405.     end
  1406.  
  1407.